home *** CD-ROM | disk | FTP | other *** search
/ Whiteline: Alpha / Whiteline Alpha.iso / progtool / modula2 / hk_lib / def_mod / longsets.mod < prev    next >
Encoding:
Modula Implementation  |  1994-09-22  |  19.5 KB  |  582 lines

  1. IMPLEMENTATION MODULE  LongSets;
  2.  
  3. (*****************************************************************************)
  4. (* Die Prozeduren werden durch die in MODULA enthaltenen Mengenoperationen,  *)
  5. (* angewendet auf jeweils einzelne BITSETs, implementiert.                   *)
  6. (*                                                                           *)
  7. (* Um ein bestimmtes Element einer Menge zu selektieren, muessen zwei Dinge  *)
  8. (* getan werden:                                                             *)
  9. (*                                                                           *)
  10. (*  - Die zum Element gehoerende BITSET muss durch                           *)
  11. (*                                                                           *)
  12. (*           menge[ VAL( CARDINAL, elem ) DIV ElementsInBITSET ]             *)
  13. (*                                                                           *)
  14. (*    ausgewaehlt werden.                                                    *)
  15. (*                                                                           *)
  16. (*  - Innerhalb dieser BITSET muss das gewuenschte Element durch             *)
  17. (*                                                                           *)
  18. (*                  VAL( CARDINAL, elem ) MOD ElementsInBITSET               *)
  19. (*                                                                           *)
  20. (*    ausgewaehlt werden.                                                    *)
  21. (*                                                                           *)
  22. (* Da der Typ "Set" aus einzelnen BITSETs zusammengesetzt ist, sind evtl.    *)
  23. (* zusaetzliche Bits vorhanden, wenn "ElementsInSet" kein Vielfaches von 16  *)
  24. (* ist. Um unerwuenschten Ergebnissen vorzubeugen, falls Bits gesetzt sind,  *)
  25. (* die nicht zur Menge gehoeren, werden diese Bits bei einigen Prozeduren ge-*)
  26. (* loescht, bzw. die Prozeduren erst gar nicht ausgefuehrt.                  *)
  27. (*___________________________________________________________________________*)
  28. (*                                                                           *)
  29. (* 04-Dez-89 , hk                                                            *)
  30. (*        Beginn                                                             *)
  31. (* 23-Dez-89 , hk                                                            *)
  32. (*        erste Version                                                      *)
  33. (* 05-Jan-90 , hk                                                            *)
  34. (*        kleinen Fehler in "IsProperSubset" beseitigt;                      *)
  35. (*        "WriteSet", "AllElements", "IsFullSet", "IsSuperset",              *)
  36. (*        "IsProperSuperset", "Equal" neu                                    *)
  37. (* 10-Jan-90 , hk                                                            *)
  38. (*        Statt ORD( elem ) wird jetzt VAL( CARDINAL, elem ) verwendet, damit*)
  39. (*        fuer DIV und MOD einfache Bitfunktionen verwendet werden, ORD lie- *)
  40. (*        fert leider ein Ergebnis vom Typ INTEGER, sodass fuer DIV und MOD  *)
  41. (*        immer Divisionsoperationen verwendet werden ( weil das Teilen ne-  *)
  42. (*        gativer Zahlen durch eine Zweierpotenz NICHT durch einen arithme-  *)
  43. (*        tischen Rechtsshift erledigt  werden kann ).                       *)
  44. (*        Neue Prozeduren "IncludeRange", "ExcludeRange"                     *)
  45. (*****************************************************************************)
  46.  
  47. FROM  SYSTEM   IMPORT  (* PROC *) VAL, INLINE, SHIFT;
  48. FROM  Terminal IMPORT  (* PROC *) Write, WriteLn;
  49.  
  50. (*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
  51.  
  52. VAR  ElemMask : BITSET; (* siehe Modulinit. *)
  53.  
  54. (*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
  55.  
  56.  
  57.   PROCEDURE  NoElements ((* -- /AUS *) VAR  menge : Set );
  58. (*T*)
  59.      VAR  Index : CARDINAL;
  60.  
  61.      BEGIN
  62.        FOR Index := 0 TO NoOfBITSETs - 1 DO
  63.           menge[ Index ] := {};
  64.        END
  65.      END  NoElements;
  66.  
  67. (*---------------------------------------------------------------------------*)
  68.  
  69.   PROCEDURE  AllElements ((* -- /AUS *) VAR  menge : Set );
  70. (*T*)
  71.      VAR  Index : CARDINAL;
  72.  
  73.      BEGIN
  74.        FOR Index := 0 TO NoOfBITSETs - 1 DO
  75.           menge[ Index ] := { 0..15 };
  76.        END;
  77.  
  78.        (* Die evtl. zusaetzlichen Bits wieder
  79.         * loeschen.
  80.         *)
  81.        menge[ NoOfBITSETs - 1 ] := menge[ NoOfBITSETs - 1 ] * ElemMask;
  82.  
  83.      END  AllElements;
  84.  
  85. (*---------------------------------------------------------------------------*)
  86.  
  87.   PROCEDURE  IsEmptySet ((* EIN/ -- *) menge : Set ): BOOLEAN;
  88. (*T*)
  89.      VAR  Index    : CARDINAL;
  90.           Zwischen : BITSET;
  91.  
  92.      BEGIN
  93.        Index := 0;
  94.  
  95.        Zwischen := menge[ NoOfBITSETs - 1 ] * ElemMask;
  96.        menge[ NoOfBITSETs - 1 ] := BITSET{0..15};
  97.  
  98.        (* Dadurch, das in <menge> auf jeden Fall eine nichtleere BITSET-
  99.         * Menge auftritt, kann die Abfrage des Index in der WHILE-
  100.         * Bedingung entfallen.
  101.         *)
  102.        WHILE   menge[ Index ] = {}   DO
  103.           INC( Index );
  104.        END;
  105.  
  106.        IF  Index = NoOfBITSETs - 1  THEN
  107.           (* Wenn <menge> bis hierhin leer ist, entscheidet
  108.            * das letzte BITSET von <menge>, ob sie wirklich
  109.            * leer ist
  110.            *)
  111.           RETURN( Zwischen = {} );
  112.        ELSE
  113.           (* sonst ist schon vorher eine BITSET-Teilmenge
  114.            * nicht leer gewesen
  115.            *)
  116.           RETURN( FALSE );
  117.        END;
  118.  
  119.      END  IsEmptySet;
  120.  
  121. (*---------------------------------------------------------------------------*)
  122.  
  123.   PROCEDURE  IsFullSet ((* EIN/ -- *) menge : Set ): BOOLEAN;
  124. (*T*)
  125.      VAR  Index    : CARDINAL;
  126.           Zwischen : BITSET;
  127.  
  128.      BEGIN
  129.        Index := 0;
  130.  
  131.        Zwischen := menge[ NoOfBITSETs - 1 ] + ( ElemMask / BITSET{ 0..15 } );
  132.  
  133.        (* Die hinteren ueberfluessigen Bits werden gesetzt,
  134.         * damit auf eine volle BITSET verglichen werden kann
  135.         *)
  136.        menge[ NoOfBITSETs - 1 ] := BITSET{ };
  137.  
  138.        (* Dadurch, das in <menge> auf jeden Fall eine leere BITSET-
  139.         * Menge auftritt, kann die Abfrage des Index in der WHILE-
  140.         * Bedingung entfallen.
  141.         *)
  142.        WHILE   menge[ Index ] = { 0..15 }   DO
  143.           INC( Index );
  144.        END;
  145.  
  146.        IF  Index = NoOfBITSETs - 1  THEN
  147.           (* Wenn <menge> bis hierhin voll ist, entscheidet
  148.            * das letzte BITSET von <menge>, ob sie wirklich
  149.            * voll ist
  150.            *)
  151.           RETURN( Zwischen = { 0..15 } );
  152.        ELSE
  153.           (* sonst ist schon vorher eine BITSET-Teilmenge
  154.            * nicht voll gewesen
  155.            *)
  156.           RETURN( FALSE );
  157.        END;
  158.  
  159.      END  IsFullSet;
  160.  
  161. (*---------------------------------------------------------------------------*)
  162.  
  163.   PROCEDURE Complement ((* EIN/ -- *)     menge : Set;
  164.                         (* -- /AUS *) VAR compl : Set  );
  165. (*T*)
  166.      VAR  Index : CARDINAL;
  167.  
  168.      BEGIN
  169.        FOR  Index := 0  TO  NoOfBITSETs - 1  DO
  170.           compl[ Index ] := menge[ Index ] / BITSET{0..15};
  171.  
  172.           (* /menge XOR 0FFFFH/ ist das gleiche wie /NOT menge/ *)
  173.        END;
  174.  
  175.        (* Die ueberfluessigen Bits muessen noch
  176.         * geloescht werden.
  177.         *)
  178.        compl[ NoOfBITSETs - 1 ] := compl[ NoOfBITSETs - 1 ] * ElemMask;
  179.  
  180.      END  Complement;
  181.  
  182. (*---------------------------------------------------------------------------*)
  183.  
  184.   PROCEDURE  Card ((* EIN/ -- *) menge : Set ): CARDINAL;
  185. (*T*)
  186.      VAR  Elemente,
  187.           Index,
  188.           Bit     : CARDINAL;
  189.  
  190.      BEGIN
  191.        (* Sicherheitshalber ueberfluessige Bits loeschen *)
  192.        menge[ NoOfBITSETs - 1 ] := menge[ NoOfBITSETs - 1 ] * ElemMask;
  193.  
  194.        Elemente := 0;
  195.  
  196.        FOR  Index := 0  TO  NoOfBITSETs - 1  DO
  197.           FOR  Bit := 0  TO  ElementsInBITSET - 1  DO
  198.              IF  Bit  IN  menge[ Index ]  THEN
  199.                 INC( Elemente );
  200.              END; (* IF Bit *)
  201.           END; (* FOR Bit *)
  202.        END; (* FOR Index *)
  203.  
  204.        RETURN( Elemente );
  205.  
  206.      END  Card;
  207.  
  208. (*---------------------------------------------------------------------------*)
  209.  
  210.   PROCEDURE  IsElement ((* EIN/ -- *) elem  : SetElement;
  211.                         (* EIN/ -- *) menge : Set        ): BOOLEAN;
  212. (*T*)
  213.      BEGIN
  214.        IF  elem <= MAX( SetElement )  THEN
  215.           (* Element nur testen, falls im gueltigen Bereich *)
  216.  
  217.           RETURN(           VAL( CARDINAL, elem ) MOD ElementsInBITSET
  218.                   IN menge[ VAL( CARDINAL, elem ) DIV ElementsInBITSET ] );
  219.        ELSE
  220.           RETURN( FALSE );
  221.        END;
  222.      END  IsElement;
  223.  
  224. (*---------------------------------------------------------------------------*)
  225.  
  226.   PROCEDURE  Include ((* EIN/ -- *)     elem  : SetElement;
  227.                       (* EIN/AUS *) VAR menge : Set        );
  228. (*T*)
  229.      BEGIN
  230.        IF  elem <= MAX( SetElement )  THEN
  231.           (* Element nur einfuegen, falls im gueltigen Bereich *)
  232.  
  233.           INCL( menge[ VAL( CARDINAL, elem ) DIV ElementsInBITSET ],
  234.                        VAL( CARDINAL, elem ) MOD ElementsInBITSET   );
  235.        END;
  236.      END  Include;
  237.  
  238. (*---------------------------------------------------------------------------*)
  239.  
  240.   PROCEDURE  Exclude ((* EIN/ -- *)     elem  : SetElement;
  241.                       (* EIN/AUS *) VAR menge : Set        );
  242. (*T*)
  243.      BEGIN
  244.        IF  elem <= MAX( SetElement )  THEN
  245.  
  246.           EXCL( menge[ VAL( CARDINAL, elem ) DIV ElementsInBITSET ],
  247.                        VAL( CARDINAL, elem ) MOD ElementsInBITSET   );
  248.        END;
  249.      END  Exclude;
  250.  
  251. (*---------------------------------------------------------------------------*)
  252.  
  253.   PROCEDURE IncludeRange ((* EIN/ -- *)     von,
  254.                           (* EIN/ -- *)     bis   : SetElement;
  255.                           (* EIN/AUS *) VAR menge : Set        );
  256. (*T*)
  257.      VAR  vonIdx,
  258.           bisIdx   : INTEGER;
  259.           vonMaske,
  260.           bisMaske : BITSET;
  261.  
  262.      BEGIN
  263.        IF  bis > MAX( SetElement )  THEN
  264.          bis := MAX( SetElement );
  265.        END;
  266.  
  267.        IF  von <= bis  THEN
  268.  
  269.           (* Erst mal die erste und die letzte BITSET auswaehlen
  270.            *)
  271.  
  272.           vonIdx   := VAL( CARDINAL, von )  DIV  ElementsInBITSET;
  273.           bisIdx   := VAL( CARDINAL, bis )  DIV  ElementsInBITSET;
  274.  
  275.           (* Die Masken fuer die gueltigen Bits in der
  276.            * ersten und der letzten BITSET berechnen
  277.            *)
  278.  
  279.           vonMaske := SHIFT( { 0..15 },
  280.                              VAL( CARDINAL, von ) MOD ElementsInBITSET );
  281.           bisMaske := SHIFT( { 0..15 },
  282.                              VAL( CARDINAL, bis ) MOD ElementsInBITSET - 15 );
  283.  
  284.  
  285.           IF  vonIdx = bisIdx  THEN
  286.  
  287.              (* Der Bereich liegt innerhalb einer einzigen
  288.               * BITSET; die Make ist daher die Schnittmenge
  289.               * der beiden Einzelmasken
  290.               *)
  291.              menge[ vonIdx ] := menge[ vonIdx ] + ( vonMaske * bisMaske );
  292.           ELSE
  293.  
  294.              (* Die Bits in der ersten und letzten betroffenen
  295.               * BITSET werden entsprechend den Masken gesetzt
  296.               * und alle dazwischenliegenden BITSETs vollstaendig
  297.               * aufgefuellt; besteht der Bereich nur aus zwei
  298.               * BITSETs, wird die Schleife nicht durchlaufen.
  299.               *)
  300.  
  301.              menge[ vonIdx ] := menge[ vonIdx ] + vonMaske;
  302.              menge[ bisIdx ] := menge[ bisIdx ] + bisMaske;
  303.  
  304.              FOR  vonIdx := vonIdx + 1  TO  bisIdx - 1  DO
  305.  
  306.                 menge[ vonIdx ] := BITSET{ 0..15 };
  307.              END; (* FOR *)
  308.  
  309.           END; (* IF vonIdx *)
  310.        END; (* IF von <= *)
  311.      END  IncludeRange;
  312.  
  313. (*---------------------------------------------------------------------------*)
  314.  
  315.   PROCEDURE ExcludeRange ((* EIN/ -- *)     von,
  316.                           (* EIN/ -- *)     bis   : SetElement;
  317.                           (* EIN/AUS *) VAR menge : Set        );
  318. (*T*) (* wie "IncludeRange *)
  319.      VAR  vonIdx,
  320.           bisIdx   : INTEGER;
  321.           vonMaske,
  322.           bisMaske : BITSET;
  323.  
  324.      BEGIN
  325.        IF  bis > MAX( SetElement )  THEN
  326.          bis := MAX( SetElement );
  327.        END;
  328.  
  329.        IF  von <= bis  THEN
  330.  
  331.           vonIdx   := VAL( CARDINAL, von )  DIV  ElementsInBITSET;
  332.           bisIdx   := VAL( CARDINAL, bis )  DIV  ElementsInBITSET;
  333.  
  334.           vonMaske := SHIFT( { 0..15 },
  335.                              VAL( CARDINAL, von ) MOD ElementsInBITSET - 16 );
  336.           bisMaske := SHIFT( { 0..15 },
  337.                              VAL( CARDINAL, bis ) MOD ElementsInBITSET + 1 );
  338.  
  339.  
  340.           IF  vonIdx = bisIdx  THEN
  341.  
  342.              menge[ vonIdx ] := menge[ vonIdx ] * ( vonMaske + bisMaske );
  343.           ELSE
  344.              menge[ vonIdx ] := menge[ vonIdx ] * vonMaske;
  345.              menge[ bisIdx ] := menge[ bisIdx ] * bisMaske;
  346.  
  347.              FOR  vonIdx := vonIdx + 1  TO  bisIdx - 1  DO
  348.  
  349.                 menge[ vonIdx ] := BITSET{ };
  350.              END; (* FOR *)
  351.           END; (* IF vonIdx *)
  352.        END; (* IF von <= *)
  353.      END  ExcludeRange;
  354.  
  355. (*---------------------------------------------------------------------------*)
  356.  
  357.   PROCEDURE  Union ((* EIN/ -- *)     menge1,
  358.                     (* EIN/ -- *)     menge2 : Set;
  359.                     (* -- /AUS *) VAR verein : Set  );
  360. (*T*)
  361.      VAR  Index : CARDINAL;
  362.  
  363.      BEGIN
  364.        FOR  Index := 0  TO  NoOfBITSETs - 1  DO
  365.           verein[ Index ] := menge1[ Index ] + menge2[ Index ];
  366.        END;
  367.      END Union;
  368.  
  369. (*---------------------------------------------------------------------------*)
  370.  
  371.   PROCEDURE  Intersection ((* EIN/ -- *)     menge1,
  372.                            (* EIN/ -- *)     menge2  : Set;
  373.                            (* -- /AUS *) VAR schnitt : Set  );
  374. (*T*)
  375.      VAR  Index : CARDINAL;
  376.  
  377.      BEGIN
  378.        FOR  Index := 0  TO  NoOfBITSETs - 1  DO
  379.           schnitt[ Index ] := menge1[ Index ] * menge2[ Index ];
  380.        END;
  381.      END Intersection;
  382.  
  383. (*---------------------------------------------------------------------------*)
  384.  
  385.   PROCEDURE  Difference ((* EIN/ -- *)     menge1,
  386.                          (* EIN/ -- *)     menge2 : Set;
  387.                          (* -- /AUS *) VAR diff   : Set  );
  388. (*T*)
  389.      VAR  Index : CARDINAL;
  390.  
  391.      BEGIN
  392.        FOR  Index := 0  TO  NoOfBITSETs - 1  DO
  393.           diff[ Index ] := menge1[ Index ] - menge2[ Index ];
  394.        END;
  395.      END Difference;
  396.  
  397. (*---------------------------------------------------------------------------*)
  398.  
  399.   PROCEDURE  SymmetricDiff ((* EIN/ -- *)     menge1,
  400.                             (* EIN/ -- *)     menge2  : Set;
  401.                             (* -- /AUS *) VAR symdiff : Set  );
  402. (*T*)
  403.      VAR  Index : CARDINAL;
  404.  
  405.      BEGIN
  406.        FOR  Index := 0  TO  NoOfBITSETs - 1  DO
  407.           symdiff[ Index ] := menge1[ Index ] / menge2[ Index ];
  408.        END;
  409.      END SymmetricDiff;
  410.  
  411. (*---------------------------------------------------------------------------*)
  412.  
  413.   PROCEDURE  Equal ((* EIN/ -- *) menge1,
  414.                     (* EIN/ -- *) menge2 : Set ): BOOLEAN;
  415. (*T*)
  416.      VAR  Index : CARDINAL;
  417.  
  418.      BEGIN
  419.        Index := 0;
  420.  
  421.        WHILE  ( Index < NoOfBITSETs                )  &
  422.               ( menge1[ Index ] = menge2[ Index ] )
  423.        DO
  424.           INC( Index );
  425.        END;
  426.  
  427.        RETURN( Index = NoOfBITSETs );
  428.  
  429.      END  Equal;
  430.  
  431. (*---------------------------------------------------------------------------*)
  432.  
  433.   PROCEDURE  IsSubset ((* EIN/ -- *) menge1,
  434.                        (* EIN/ -- *) menge2 : Set ): BOOLEAN;
  435. (*T*)
  436.      VAR  Index : CARDINAL;
  437.  
  438.      BEGIN
  439.        Index := 0;
  440.  
  441.        WHILE  ( Index < NoOfBITSETs                )  &
  442.               ( menge1[ Index ] <= menge2[ Index ] )
  443.        DO
  444.           (* Nach der ersten BITSET von <menge1> abbrechen,
  445.            * die keine Untermenge der BITSET von <menge2> ist
  446.            *)
  447.           INC( Index );
  448.        END;
  449.  
  450.        RETURN( Index = NoOfBITSETs );
  451.  
  452.      END  IsSubset;
  453.  
  454. (*---------------------------------------------------------------------------*)
  455.  
  456.   PROCEDURE  IsProperSubset ((* EIN/ -- *) menge1,
  457.                              (* EIN/ -- *) menge2 : Set ): BOOLEAN;
  458. (*T*)
  459.     VAR  Index    : CARDINAL;
  460.          Ungleich : BOOLEAN;
  461.  
  462.     BEGIN
  463.        Index := 0;
  464.        Ungleich := FALSE;
  465.  
  466.        WHILE  ( Index < NoOfBITSETs                )  &
  467.               ( menge1[ Index ] <= menge2[ Index ] )
  468.        DO
  469.           (* Es reicht, wenn nur eine einzige BITSET
  470.            * unterschiedlich ist.
  471.            *)
  472.           Ungleich := Ungleich OR ( menge1[ Index ] #  menge2[ Index ] );
  473.           INC( Index );
  474.        END;
  475.  
  476.        RETURN(( Index = NoOfBITSETs ) & Ungleich );
  477.  
  478.   END  IsProperSubset;
  479.  
  480. (*---------------------------------------------------------------------------*)
  481.  
  482.   PROCEDURE  IsSuperset ((* EIN/ -- *) menge1,
  483.                          (* EIN/ -- *) menge2 : Set ): BOOLEAN;
  484. (*T*)
  485.      VAR  Index : CARDINAL;
  486.  
  487.      BEGIN
  488.        Index := 0;
  489.  
  490.        WHILE  ( Index < NoOfBITSETs                )  &
  491.               ( menge1[ Index ] >= menge2[ Index ] )
  492.        DO
  493.           INC( Index );
  494.        END;
  495.  
  496.        RETURN( Index = NoOfBITSETs );
  497.  
  498.      END  IsSuperset;
  499.  
  500. (*---------------------------------------------------------------------------*)
  501.  
  502.   PROCEDURE  IsProperSuperset ((* EIN/ -- *) menge1,
  503.                                (* EIN/ -- *) menge2 : Set ): BOOLEAN;
  504. (*T*)
  505.     VAR  Index    : CARDINAL;
  506.          Ungleich : BOOLEAN;
  507.  
  508.     BEGIN
  509.        Index := 0;
  510.        Ungleich := FALSE;
  511.  
  512.        WHILE  ( Index < NoOfBITSETs                )  &
  513.               ( menge1[ Index ] >= menge2[ Index ] )
  514.        DO
  515.           (* Es reicht, wenn nur eine einzige BITSET
  516.            * unterschiedlich ist.
  517.            *)
  518.           Ungleich := Ungleich OR ( menge1[ Index ] #  menge2[ Index ] );
  519.           INC( Index );
  520.        END;
  521.  
  522.        RETURN(( Index = NoOfBITSETs ) & Ungleich );
  523.  
  524.   END  IsProperSuperset;
  525.  
  526. (*---------------------------------------------------------------------------*)
  527.  
  528.   PROCEDURE  WriteSet ((* EIN/ -- *) menge : Set);
  529. (*T*)
  530.      VAR  Bitset : INTEGER;  (* Falls NoOfBITSETs = 1 *)
  531.           Bit    : CARDINAL;
  532.  
  533.      BEGIN
  534.        FOR  Bitset := 0  TO  NoOfBITSETs - 2  DO
  535.           FOR  Bit := 0  TO  15  DO
  536.              IF  Bit  IN  menge[ Bitset ]  THEN
  537.                 Write('1');
  538.              ELSE
  539.                 Write('0');
  540.              END;
  541.           END;
  542.           Write('|');
  543.  
  544.           (* Pro Zeile vier BITSETs ausgeben
  545.            *)
  546.           IF  ( Bitset + 1 ) MOD 4 = 0  THEN  WriteLn; END;
  547.        END;
  548.  
  549.        (* Letzte BITSET wegen der evtl. zusaetzl.
  550.         * Bits gesondert behandeln
  551.         *)
  552.        FOR  Bit := 0  TO  LastElements - 1  DO
  553.           IF  Bit  IN  menge[ Bitset ]  THEN
  554.              Write('1');
  555.           ELSE
  556.              Write('0');
  557.           END;
  558.        END;
  559.        Write('|');
  560.  
  561.      END  WriteSet;
  562.  
  563. (*---------------------------------------------------------------------------*)
  564.  
  565. BEGIN (* Sets-Initialisierung *)
  566.  
  567.   (* Mit dieser Maske werden die gueltigen Bits der letzten
  568.    * BITSET maskiert.
  569.    * Das Wort mit dem Wert 0FFFFH - also alle Bits gesetzt -
  570.    * wird um soviele Bits nach links geschoben wie gueltige
  571.    * Bits in der letzten BITSET sind. Dann werden alle Bits
  572.    * invertiert, d.h. dort wo gueltige Bits stehen sollen
  573.    * ( von rechts betrachtet ), sind die Bits der Maske
  574.    * gesetzt, alle weiteren Bits sind geloescht, sodass
  575.    * bei einer UND-Verknuepfung ( durch den Vereinigungs-
  576.    * operator '*' ) alle ungueltigen Bits geloescht werden.
  577.    *)
  578.  
  579.   ElemMask := SHIFT( BITSET{ 0..15 }, LastElements ) / BITSET{ 0..15 };
  580.  
  581. END  LongSets.
  582.